package cn.tedu.sjmall.seckill.webapi.seckill.consumer;

import cn.tedu.sjmall.pojo.seckill.model.Success;
import cn.tedu.sjmall.seckill.webapi.seckill.config.RabbitMqComponentConfiguration;
import cn.tedu.sjmall.seckill.webapi.seckill.mapper.SeckillSkuMapper;
import cn.tedu.sjmall.seckill.webapi.seckill.mapper.SuccessMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = RabbitMqComponentConfiguration.SECKILL_QUEUE)
@Slf4j
public class SeckillQueueConsumer {

    @Autowired
    private SeckillSkuMapper seckillSkuMapper;
    @Autowired
    private SuccessMapper successMapper;

    // 下面的方法会在消息队列有消息时自动运行
    // 方法的参数就是发送来的消息对象
    @RabbitHandler
    public void process(Success success){
        // 先连接数据库操作修改库存(没有必须的先后顺序)
        seckillSkuMapper.updateReduceStockBySkuId(
                success.getSkuId(),success.getQuantity());
        // 再新增success到数据库表
        successMapper.saveSuccess(success);

        // 上面代码是两次连续的数据库更新操作,正常逻辑需要保证事务
        // 但是当前是在消息队列中,无法使用常规事务,如果不需要精确统计时,发生的异常可以忽略
        // 但如果需要精确统计,就需要将上面的每次数据库操作使用try-catch管理
        // 在catch中进行重试操作,如果还不行,考虑使用死信队列
        // 死信队列在实际开发中还是要谨慎使用的

    }


}





